package com.haoqizhe.kernel.mybatis.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haoqizhe.kernel.commons.enums.ConditionEnum;
import com.haoqizhe.kernel.core.entity.PageView;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author haoqizhe.li
 * @date 2021/6/29 14:36
 */
public class ParamUtil {

    private static final String ORDER_BY = "_order_by";
    private static final String DESC = "desc";


    /**
     * 统一构造分页响应
     *
     * @param page
     * @param <T>
     * @return
     */
    public static <T> PageView<T> pageBuild(Page<T> page) {
        PageView<T> pv = new PageView<>();

        pv.setTotal(page.getTotal());
        pv.setList(page.getRecords());
        pv.setPageSize((int) page.getSize());
        pv.setPageNum((int) page.getCurrent());
        pv.setPages((int) page.getPages());

        return pv;
    }


    /**
     * 封装map 查询参数
     *
     * @return
     * @throws
     * @author haoqizhe.li
     * @date 2018/4/8 13:51
     **/
    public static <T> void setWrapper(String key, String value, QueryWrapper<T> wrapper) {
        String prop = StrUtil.subBefore(key, "#", false);
        String op = StrUtil.subAfter(key, "#", false);

        if (StrUtil.isBlank(prop)) {
            return;
        }
        prop = prop.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();

        if (StrUtil.isNotBlank(value)) {
            if (ConditionEnum.LIKE.code.equals(op)) {
                wrapper.like(prop, value);
            } else if (ConditionEnum.GE.code.equals(op)) {
                wrapper.ge(prop, value);
            } else if (ConditionEnum.GT.code.equals(op)) {
                wrapper.gt(prop, value);
            } else if (ConditionEnum.IN.code.equals(op)) {
                wrapper.in(prop, Arrays.asList(value.split(",")));
            } else if (ConditionEnum.LE.code.equals(op)) {
                wrapper.le(prop, value);
            } else if (ConditionEnum.LT.code.equals(op)) {
                wrapper.lt(prop, value);
            } else if (ConditionEnum.NOT_EQ.code.equals(op) || ConditionEnum.NE.code.equals(op)) {
                wrapper.ne(prop, value);
            } else if (ConditionEnum.NOT_LIKE.code.equals(op) || ConditionEnum.NL.code.equals(op)) {
                wrapper.notLike(prop, value);
            } else if (ConditionEnum.NOT_IN.code.equals(op) || ConditionEnum.NI.code.equals(op)) {
                wrapper.notIn(prop, Arrays.asList(value.split(",")));
            } else {
                wrapper.eq(prop, value);
            }
        } else {
            if (ConditionEnum.NOT_NULL.code.equals(op) || ConditionEnum.NN.code.equals(op)) {
                wrapper.isNotNull(prop);
            } else if (ConditionEnum.NULL.code.equals(op)) {
                wrapper.isNull(prop);
            }
        }
    }

    public static <T> QueryWrapper<T> getWrapperByMap(Map<String, String> map, List<String> ignoreKeyList) {
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        for (String key : map.keySet()) {
            if (ORDER_BY.equals(key)) {
                setOrderBy(map.get(key), wrapper);
                continue;
            }
            if (CollUtil.isNotEmpty(ignoreKeyList) && ignoreKeyList.contains(key)) {
                continue;
            }
            setWrapper(key, map.get(key), wrapper);
        }

        return wrapper;
    }

    public static <T> void setOrderBy(String value, QueryWrapper<T> wrapper) {
        if (StrUtil.isBlank(value)) {
            return;
        }
        String[] arr = value.split(",");
        String[] columns = null;
        String column = null;
        for (String s : arr) {
            columns = s.split(" ");
            switch (columns.length) {
                case 1:
                    column = columns[0].trim().replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
                    wrapper.orderByAsc(column);
                    break;
                case 2:
                    column = columns[0].trim().replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
                    if (!DESC.equals(columns[1].trim())) {
                        wrapper.orderByAsc(column);
                    } else {
                        wrapper.orderByDesc(column);
                    }
                    break;
                default:
                    continue;
            }
        }
    }
}
